// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

#region File Information
//-----------------------------------------------------------------------------
// Human.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
#endregion

namespace HexTD
{
	class GameBoard : DrawableGameComponent
	{
		#region Fields/Constants
		Game game;
		Context context;
		SpriteBatch spriteBatch;
		PrimitiveBatch primitiveBatch;
		SpriteFont hudFont;
		//Drag variables to hold first and last gesture samples
		GestureSample? prevSample;
		GestureSample? firstSample;
		public bool isDragging;
		// Constant for longest distance possible between drag points
		readonly float maxDragDelta = (new Vector2(480, 800)).Length();

		public bool IsActive { get; set; }

		#endregion

		#region Initialization
		public GameBoard(Game game, SpriteBatch screenSpriteBatch, Context context) : base(game)
		{
			primitiveBatch = new PrimitiveBatch(game.GraphicsDevice);

			this.game = game;
			this.context = context;
			spriteBatch = screenSpriteBatch;
		}

		public override void Initialize()
		{
		}
		#endregion

		#region Handle Input
		/// <summary>
		/// Function processes the user input
		/// </summary>
		/// <param name="gestureSample"></param>
		public void HandleInput(GestureSample gestureSample)
		{
			// Process input only if in Human's turn
			if (IsActive)
			{
				// Process any Drag gesture
				if (gestureSample.GestureType == GestureType.FreeDrag)
				{
					// If drag just began save the sample for future 
					// calculations and start Aim "animation"
					if (null == firstSample)
					{
						firstSample = gestureSample;
					}

					// save the current gesture sample 
					prevSample = gestureSample;

					// calculate the delta between first sample and current
					// sample to present visual sound on screen
					Vector2 delta = prevSample.Value.Position -
						firstSample.Value.Position;
					isDragging = true;
				}
				else if (gestureSample.GestureType == GestureType.DragComplete)
				{
					// calc velocity based on delta between first and last
					// gesture samples
					if (null != firstSample)
					{
						Vector2 delta = prevSample.Value.Position -
							firstSample.Value.Position;
					}

					// turn off dragging state
					ResetDragState();
				}
			}
		}
		#endregion

		#region Draw
		public override void Draw(GameTime gameTime)
		{
			DrawSun(new Vector2(400, 400));
			DrawBoard(gameTime);

			base.Draw(gameTime);
		}
		#endregion

		#region DrawHelpers
		void DrawBoard(GameTime gameTime)
		{
			if (context.grid != null)
			{
				for (int y = 0; y < this.context.grid.GetLength(1); y++)
				{
					int xLength = this.context.grid.GetLength(0) - (y & 1);
					for (int x = 0; x < xLength; x++)
					{
						this.context.grid[x, y].Draw(gameTime);
					}
				}
			}

		}

		/// <summary>
		/// A simple helper to draw shadowed text.
		/// </summary>
		void DrawString(SpriteFont font, string text, Vector2 position, Color color)
		{
			spriteBatch.DrawString(font, text,
				new Vector2(position.X + 1, position.Y + 1), Color.Black);
			spriteBatch.DrawString(font, text, position, color);
		}

		// called to draw the spacewars sun.
		private void DrawSun(Vector2 where)
		{
			float SunSize = 100f;

			// the sun is made from 4 lines in a circle.
			primitiveBatch.Begin(PrimitiveType.LineList);

			// draw the vertical and horizontal lines
			primitiveBatch.AddVertex(where + new Vector2(0, SunSize), Color.White);
			primitiveBatch.AddVertex(where + new Vector2(0, -SunSize), Color.White);

			primitiveBatch.AddVertex(where + new Vector2(SunSize, 0), Color.White);
			primitiveBatch.AddVertex(where + new Vector2(-SunSize, 0), Color.White);

			// to know where to draw the diagonal lines, we need to use trig.
			// cosine of pi / 4 tells us what the x coordinate of a circle's radius is
			// at 45 degrees. the y coordinate normally would come from sin, but sin and
			// cos 45 are the same, so we can reuse cos for both x and y.
			float sunSizeDiagonal = (float)Math.Cos(MathHelper.PiOver4);

			// since that trig tells us the x and y for a unit circle, which has a
			// radius of 1, we need scale that result by the sun's radius.
			sunSizeDiagonal *= SunSize;

			primitiveBatch.AddVertex(
				where + new Vector2(-sunSizeDiagonal, sunSizeDiagonal), Color.Gray);
			primitiveBatch.AddVertex(
				where + new Vector2(sunSizeDiagonal, -sunSizeDiagonal), Color.Gray);

			primitiveBatch.AddVertex(
				where + new Vector2(sunSizeDiagonal, sunSizeDiagonal), Color.Gray);
			primitiveBatch.AddVertex(
				where + new Vector2(-sunSizeDiagonal, -sunSizeDiagonal), Color.Gray);

			primitiveBatch.End();
		}
		#endregion

		/// <summary>
		/// Turn off dragging state and reset drag related variables
		/// </summary>
		public void ResetDragState()
		{
			firstSample = null;
			prevSample = null;
			isDragging = false;
		}
	}
}
